package com.atzxh.guigu.juc.readwrite;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 小红同学
 * @create 2023-04-28-10:48
 * @description  读写锁的应用示例    写锁：独占锁     读锁：共享锁
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        // 创建线程写数据
        for (int i = 1; i < 5; i++) {
            int num = i;
            new Thread(()->{
                myCache.put(num+"",num);
            },String.valueOf(i)).start();
        }
        // 创建线程读数据
        for (int i = 1; i < 5; i++) {
            int num = i;
            new Thread(()->{
                myCache.get(num+"");
            },String.valueOf(i)).start();
        }
    }
}

// 资源类
class MyCache {
    public volatile Map<String,Object> map = new HashMap<>();
    // 创建读写锁的对象
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    // 写数据
    public void put(String key, Object value) {
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + "   正在写操作   " + key);
            // 暂停一会
            TimeUnit.MILLISECONDS.sleep(200);
            // 写数据
            map.put(key,value);
            // 结束
            System.out.println(Thread.currentThread().getName() + "  写完了  " + key);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
    // 读数据
    public Object get(String key) {
        readWriteLock.readLock().lock();
        Object result = null;
        try {
            System.out.println(Thread.currentThread().getName() + "  正在读数据  " + key);
            // 暂停一会
            TimeUnit.MILLISECONDS.sleep(200);
            // 获取数据
            result = map.get(key);
            System.out.println(Thread.currentThread().getName() + "  读完了  " + result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
        return result;
    }
}
